package com.midea.ai.air.utils;

import android.os.AsyncTask;

import com.alibaba.fastjson.JSON;
import com.midea.ai.air.data.ResultModel;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;

import org.json.JSONException;

import java.io.IOException;
import java.util.HashMap;

/**
 * Created by QiuDa on 15/11/28.
 */
public class HttpUtils {
    private HashMap<String, Object> mRequestLit = new HashMap<>();
    private static final String TAG = "HttpUtils";
    public static final MediaType TYPE_JSON
            = MediaType.parse("application/json; charset=utf-8");
    private OkHttpClient client = new OkHttpClient();
    private callBack mCall;


    public HttpUtils(callBack call) {
        this.mCall = call;
    }

    /**
     * get方法
     *
     * @param url 请求url
     * @return 结果
     * @throws IOException
     */
    public synchronized boolean get(String url) {
        synchronized (mRequestLit) {
            if (mRequestLit.containsKey(url)) {
                return false;
            }
        }
        mRequestLit.put(url, null);
        Request request = new Request.Builder()
                .url(url)
                .build();
        HttpAsync async = new HttpAsync();
        async.execute(request);
        return true;
    }


    /**
     * Post方法
     *
     * @param url         请求url
     * @param requestBody 请求参数
     * @return 结果
     * @throws IOException
     */
    public synchronized boolean post(String url, RequestBody requestBody) {
        synchronized (mRequestLit) {
            if (mRequestLit.containsKey(url)) {
                return false;
            }
        }
        mRequestLit.put(url, requestBody);
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();
        HttpAsync async = new HttpAsync();
        async.execute(request);
        return true;
    }

    /**
     * Post方法
     *
     * @param url  请求url
     * @param json 请求参数
     * @return 结果
     * @throws IOException
     */
    public synchronized boolean post(String url, String json) {
        synchronized (mRequestLit) {
            if (mRequestLit.containsKey(url)) {
                return false;
            }
        }
        mRequestLit.put(url, json);
        RequestBody body = RequestBody.create(TYPE_JSON, json);
        Request request = new Request.Builder()
                .url(url)
                .post(body)
                .build();
        HttpAsync async = new HttpAsync();
        async.execute(request);
        return true;
    }

    /**
     * 请求处理
     *
     * @param request request对象
     * @return
     */
    private ResultModel processRequest(Request request) {
        ResultModel resultModel = null;
        try {
            Response response = client.newCall(request).execute();
            if (response == null) {
                mCall.onError(request.urlString(), new IOException());
                return null;
            }
            String resultjson = response.body().string();
            L.d(TAG + "_URL", response.request().urlString());
            L.d(TAG + "_RESULT", resultjson);
            resultModel = JSON.parseObject(resultjson, ResultModel.class);
            resultModel.setUrl(response.request().urlString());
            resultModel.setJson(resultjson);
            Object obj = mCall.asyncExecute(request.urlString(), resultModel);
            resultModel.setDataModel(obj);
        } catch (Exception e) {
            L.e(TAG, e);
            if (mCall != null) {
                mCall.onError(request.urlString(), e);
            }
        }
        return resultModel;
    }

    /**
     * 处理请求结果
     *
     * @param resultModel 请求结果
     */
    private void processResult(ResultModel resultModel) {
        if (resultModel == null) {
            return;
        }
        try {
            if ("0".equals(resultModel.getErrCode())) {
                mCall.onSucceed(resultModel.getUrl(), resultModel);
            } else {
                mCall.onFailure(resultModel.getUrl(), resultModel);
            }
        } catch (Exception e) {
            L.e(TAG, e);
            if (mCall != null) {
                mCall.onError(resultModel.getUrl(), e);
            }
        }
    }

    class HttpAsync extends AsyncTask<Request, Integer, ResultModel> {


        @Override
        protected ResultModel doInBackground(Request... params) {
            if (mCall == null || params == null || params.length == 0) {
                return null;
            }
            ResultModel resultModel = processRequest(params[0]);
            return resultModel;
        }


        @Override
        protected void onPostExecute(ResultModel result) {
//            super.onPostExecute(response);
            processResult(result);
            synchronized (mRequestLit) {
                if (result != null)  //todo: maxxiang, 连不上server时，result为空，会crash.
                    mRequestLit.remove(result.getUrl());
            }
        }
    }


    /**
     * 请求数据返回的回调函数类
     */
    public interface callBack {
        /**
         * get请求
         *
         * @param url
         */
        boolean get(String url);

        /**
         * post请求
         *
         * @param url
         * @param json
         */
        boolean post(String url, String json);

        boolean post(String url, RequestBody requestBody);

        /**
         * 请求错误
         *
         * @param url url
         * @param e   错误
         */
        void onError(String url, Exception e);

        /**
         * 异步处理（同步get调用才有效）
         *
         * @param url         url
         * @param resultModel 结果对象
         */

        Object asyncExecute(String url, ResultModel resultModel);

        /**
         * 请求失败
         *
         * @param url         url
         * @param resultModel 结果对象
         */
        void onFailure(String url, ResultModel resultModel);

        /**
         * 请求成功
         *
         * @param url         url
         * @param resultModel 结果对象
         */
        void onSucceed(String url, ResultModel resultModel) throws JSONException;

    }

}
